package controllers;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.util.ArrayList;

import javax.swing.JSlider;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

import models.AttractorGen;

import views.Canvas;
import views.MainWindow;

public class MainController implements ActionListener, ChangeListener
{
	private AttractorGen 			ag				= null;
	private MainWindow				window			= null;
	private float					oldStep			= 0.f;
	
	public MainController(boolean outputMode, int outputQuantity)
	{
		ag = new AttractorGen(this, outputMode, outputQuantity);
	}
	
	public void actionPerformed(ActionEvent e)
	{
		if (e.getActionCommand() == "CALC")
		{
			Canvas.CALC = !Canvas.CALC;
		}
		
		if (e.getActionCommand() == "PAUSE")
		{
			if (Canvas.CALC)
				Canvas.PAUSE = !Canvas.PAUSE;
		}
		
		if (e.getActionCommand() == "SHOW_DEBUG")
		{
			Canvas.SHOW_DEBUG = !Canvas.SHOW_DEBUG;
		}
		
		if (e.getActionCommand() == "EXIT")
		{
			System.exit(1);
		}
		
		if (e.getActionCommand() == "PICKOVER")
		{
			Canvas.CUSTOM = false;
			Canvas.DEJONG = false;
			Canvas.PICKOVER = true;
		}
		
		if (e.getActionCommand() == "DEJONG")
		{
			Canvas.CUSTOM = false;
			Canvas.DEJONG = true;
			Canvas.PICKOVER = false;
		}
		
		if (e.getActionCommand() == "CUSTOM")
		{
			Canvas.CUSTOM = true;
			Canvas.DEJONG = false;
			Canvas.PICKOVER = false;
		}
		
		if (e.getActionCommand() == "BW")
		{
			Canvas.BW = true;
			Canvas.COLOR = false;
		}
		
		if (e.getActionCommand() == "COLOR")
		{
			Canvas.BW = false;
			Canvas.COLOR = true;
		}
		
		if (e.getActionCommand() == "STATIC")
		{
			oldStep = window.getCP().getSliderItem().getValue() / 10000f;
			window.getCP().getSliderItem().setValue(0);
		}
		
		if (e.getActionCommand() == "DYNAMIC")
		{
			window.getCP().setSliderItemValue(oldStep);
		}
		
		if (e.getActionCommand() == "ADD_VAR")
		{
			window.getCP().getVarPanel().addVar();
			window.validate();
		}
		
		if (e.getActionCommand() == "REMOVE_VAR")
		{
			window.getCP().getVarPanel().removeVar();
			window.validate();
		}
		
		if (e.getActionCommand() == "SET_PTS_NR")
		{
			int val = Integer.valueOf(window.getCP().getPointsNumberFromTF());
			if (val <= AttractorGen.MAX_NR_OF_PTS)
				AttractorGen.NR_OF_PTS = val;
		}
	}

	@Override
	public void stateChanged(ChangeEvent e)
	{
		JSlider source = (JSlider) e.getSource();
		DecimalFormatSymbols coma = new DecimalFormatSymbols();
		coma.setDecimalSeparator('.');
		DecimalFormat df = new DecimalFormat("#.#####",coma);

		if (!source.getValueIsAdjusting())
		{
			window.getCP().getSliderLabel().setText(String.valueOf(df.format(source.getValue() / 100000.d)));
			AttractorGen.STEP = source.getValue() / 100000.f;
		}	
	}
	
	// TODO: Really should re-think this...
	public AttractorGen getAG()
	{
		return ag;
	}
	
	public String getEquation(String eq)
	{
		if (eq.equals("X"))
			return window.getCP().getEqX();
		else if (eq.equals("Y"))
			return window.getCP().getEqY();
		else if (eq.equals("Z"))
			return window.getCP().getEqZ();
		else
			return new String();
		// FIXME: Should consider making a protection for this...
	}
	
	/**
	 * Register the var to the varList with the default value of 0
	 * 
	 * @param varName - name of the var to register
	 */
	public void addVar(String varName)
	{
		ag.addVar(varName, 0);		
	}

	public void removeVar(String varName)
	{
		ag.removeVar(varName);
	}

	public ArrayList<String> getVars()
	{
		return window.getCP().getVarPanel().getVars();
	}
	
	public void setVars(double step)
	{
		window.getCP().getVarPanel().setVars(step);
	}
	
	public void run()
	{
		if (window == null)
		{			
			window = new MainWindow(this);
			window.run();
		}
	}
	
	/**
	 * @param args
	 */
	public static void main(String[] args)
	{
		MainController main = null;
		
		if (args.length == 2 && args[0].equals("OUTPUT"))
		{
			try
			{
				// program args example: OUTPUT 3
				main = new MainController(true, Integer.valueOf(args[1]));
			}
			catch (NumberFormatException nfe)
			{
				System.err.println("The second parameter must be an integer");
			}
		}
		else
		{
			main = new MainController(false, 0);	
		}
		
		if (main != null)
			main.run();
	}
}
